const path = require("path");
const webpack = require("webpack");
const fs = require("fs-extra");
// const ExtractTextPlugin = require("extract-text-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { VueLoaderPlugin } = require("vue-loader");
const ManifestPlugin = require("webpack-manifest-plugin");
const ProgressBarPlugin = require("progress-bar-webpack-plugin");
var HtmlWebpackPlugin = require("html-webpack-plugin");
const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin");
// var Dashboard = require('webpack-dashboard');
// var DashboardPlugin = require('webpack-dashboard/plugin');
// var dashboard = new Dashboard();

const Monitor = require("../plugins/Monitor");

const paths = require("./paths");
const { npmSingle } = require("./compress");
const faviconExists = fs.existsSync(path.join(paths.appPublic, "favicon.ico"));
const venderPattern = new RegExp(`[\\/]node_modules[\\/](${npmSingle.join("|")})`);

let assetPath = paths.assetsPath;
assetPath = assetPath.replace(/^\/|\/$/g, "");

module.exports = {
  mode: "development",
  devtool: "eval-source-map",
  entry:
    paths.appName == "odcp-console-header"
      ? [paths.appIndexJs]
      : [require.resolve("babel-polyfill"), paths.appIndexJs],
  output: {
    path: paths.appBuild,
    filename: `${assetPath}/static/js/bundle.js`,
    publicPath: "/",
    chunkFilename: `${assetPath}/static/js/[name].chunk.js`,
    library: paths.appName,
    libraryTarget: "umd",
    jsonpFunction: `webpackJsonp_${paths.appName}`
  },
  optimization: {
    splitChunks: {
      chunks: "all",
      name: true,
      maxInitialRequests: Infinity,
      cacheGroups: {
        vendor: {
          test: venderPattern,
          name(module, chunks, cacheGroupKey) {
            // get the name. E.g. node_modules/packageName/not/this/part.js
            // or node_modules/packageName
            const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];

            // npm package names are URL-safe, but some servers don't like @ symbols
            return `npm.${packageName.replace("@", "")}`;
          }
        }
      }
    },
    runtimeChunk: true
  },
  resolve: {
    modules: ["node_modules", paths.appNodeModules],
    alias: {
      CONFIG: paths.appConfigs,
      ASSETS: paths.appAssets,
      STORE: paths.appStore,
      ROUTER: paths.appRouter,
      SERVICE: paths.appService,
      UTIL: paths.appUtil,
      VIEW: paths.appView,
      API: paths.appApi
    },
    extensions: [".js", ".json", ".vue", ".css", ".scss", ".ts"]
  },
  externals: {
    vue: "Vue",
    ELEMENT: "ELEMENT",
    "vue-router": "VueRouter"
  },
  module: {
    rules: [
      // {
      //   enforce: 'pre',
      //   test: /\.(js|vue)$/,
      //   // loader: 'eslint-loader',
      //   exclude: /node_modules/,
      //   use: [
      //     {
      //       options: {
      //         // formatter: eslintFormatter,
      //         parser: "babel-eslint",
      //         eslintPath: require.resolve("eslint"),
      //         // baseConfig: {
      //         //   extends: [require.resolve("eslint-config-react-app")]
      //         // },
      //         ignore: false,
      //         useEslintrc: false
      //       },
      //       loader: require.resolve("eslint-loader")
      //     }
      //   ],
      // },

      // 'transform-runtime' 插件告诉 babel 要引用 runtime 来代替注入。
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["env", "stage-1", "stage-2"],
            plugins: [
              "transform-runtime",
              "syntax-dynamic-import",
              "syntax-jsx",
              "transform-decorators-legacy",
              "transform-vue-jsx",
              [
                "component",
                {
                  libraryName: "element-ui",
                  styleLibraryName: "theme-chalk"
                }
              ]
            ]
          }
        }
      },
      // {
      //   test: /\.ts$/,
      //   exclude: /node_modules/,
      //   enforce: 'pre',
      //   loader: 'tslint-loader'
      // },
      {
        test: /\.tsx?$/,
        loader: "ts-loader",
        exclude: /node_modules/,
        options: {
          appendTsSuffixTo: [/\.vue$/]
        }
      },
      {
        test: /\.vue$/,
        loader: "vue-loader",
        options: {
          extractCSS: true
        }
      },
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              hmr: process.env.NODE_ENV === "development"
            }
          },
          "css-loader",
          "sass-loader"
        ]
      },

      // {
      //   test: /\.css$/,
      //   use: ExtractTextPlugin.extract({
      //     fallback: "style-loader",
      //     use: ["css-loader"]
      //   })
      // },
      // {
      //   test: /\.scss$/,
      //   use: ExtractTextPlugin.extract({
      //     use: ["css-loader", "sass-loader"],
      //     // 在开发环境使用 style-loader
      //     fallback: "style-loader"
      //   })
      // },
      {
        test: /\.(png|(jpe?g)|gif|svg)$/,
        use: [
          {
            loader: "url-loader",
            options: {
              limit: 10000,
              name: `${assetPath}/static/image/[name].[hash:8].[ext]`
            }
          }
        ]
      },
      {
        test: /\.(eot|svg|ttf|woff|woff2)$/,
        loader: "file-loader"
      }
      // {
      //   exclude: [/\.(js|jsx|mjs|vue)$/, /\.html$/, /\.json$/],
      //   loader: require.resolve("file-loader"),
      //   options: {
      //     name: "static/media/[name].[hash:8].[ext]"
      //   }
      // }
    ]
  },

  plugins: [
    new HtmlWebpackPlugin({
      // Also generate a index.html
      title: "create aife",
      inject: true,
      filename: "index.html",
      template: "public/index.html",
      favicon: faviconExists ? "public/favicon.ico" : ""
    }),
    new ScriptExtHtmlWebpackPlugin({
      custom: {
        test: /\.js$/,
        attribute: "crossorigin",
        value: "anonymous"
      }
    }),
    new VueLoaderPlugin(),
    // new ExtractTextPlugin({
    //   filename: "static/css/[name].[hash:8].css"
    // }),
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: `${assetPath}/static/css/[name].[hash:8].css`
      // chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
    }),
    new webpack.DefinePlugin({
      "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || "development"),
      "process.env.VUE_ENV": '"client"'
    }),
    // webpack-dev-server 强化插件
    // new DashboardPlugin(dashboard.setData),
    new webpack.HotModuleReplacementPlugin(),
    new ProgressBarPlugin(),

    new ManifestPlugin({
      fileName: "asset-manifest.json"
    })
  ],
  // Some libraries import Node modules but don't use them in the browser.
  // Tell Webpack to provide empty mocks for them so importing them works.
  node: {
    dgram: "empty",
    fs: "empty",
    net: "empty",
    tls: "empty",
    child_process: "empty"
  },
  // Turn off performance processing because we utilize
  // our own hints via the FileSizeReporter
  performance: false
};
